
#include once "math/vecf.bi"
#include once "math/matrix4x4f.bi"

constructor vec4f ( byval x as single, byval y as single, byval z as single, byval w as double )
    
	this.x = x
	this.y = y
	this.z = z
	this.w = w
    
end constructor


constructor vec4f ( byref v4d as vec4f )
    
	this.x = v4d.x
	this.y = v4d.y
	this.z = v4d.z
	this.w = v4d.w
    
end constructor


constructor vec4f ( )
    
	this.x = 0.0
	this.y = 0.0
	this.z = 0.0
	this.w = 0.0
    
end constructor


function vec4f.dot ( byref v as vec4f ) as MATH_PRECISION
    
    return  this.x * v.x + this.y * v.y + this.z * v.z + this.w * v.w
    
end function


function vec4f.magnitude( ) as MATH_PRECISION
    
    dim Mag as MATH_PRECISION = any
    mag = sqr( this.x ^2 + this.y ^2 + this.z ^2 + this.w ^2 )
    if mag = 0 then mag = 1
    return mag
    
end function


sub vec4f.normalize()
    
	this = this / this.magnitude()
    
end sub


function vec4f.UnitVec() as vec4f
    
	 return this / this.magnitude()
	
end function


function vec4f.cross( byref v as vec4f ) as vec4f
    
	return type<vec4f>((this.y * v.z) - (v.y * this.z), (this.z * v.x) - (v.z * this.x), (this.x * v.y) - (v.x * this.y), this.w)
    
end function


function vec4f.distance( byref v as vec4f ) as MATH_PRECISION
    
	return sqr((v.x - this.x)^2 + (v.y - this.y)^2 + (v.z - this.z)^2)
    
end function


operator vec4f.cast() as string
    
	return "x: " & this.x & ", y: " & this.y & ", z: " & this.z & ", w: " & this.w
    
end operator


operator vec4f.cast() as vec3f
    
	return type<vec3f>(this.x, this.y, this.z)
    
end operator


operator + ( byref lhs as vec3f, byref rhs as double ) as vec4f
    
	return type<vec4f>( lhs.x, lhs.y, lhs.z, rhs )
    
end operator


operator + ( byref lhs as vec4f, byref rhs as vec4f ) as vec4f
    
	return type<vec4f>( lhs.x + rhs.x, lhs.y + rhs.y, lhs.z + rhs.z, lhs.w + rhs.w )
    
end operator


operator + ( byref lhs as vec4f, byref rhs as single ) as vec4f
    
	return type<vec4f>( lhs.x + rhs, lhs.y + rhs, lhs.z + rhs, lhs.w + rhs )
    
end operator


operator - ( byref lhs as vec4f, byref rhs as vec4f ) as vec4f
    
	return type<vec4f>( lhs.x - rhs.x, lhs.y - rhs.y, lhs.z - rhs.z, lhs.w - rhs.w )
    
end operator


operator * ( byref lhs as vec4f, byref rhs as vec4f ) as vec4f
    
	return type<vec4f>( lhs.x * rhs.x, lhs.y * rhs.y, lhs.z * rhs.z, lhs.w * rhs.w )
    
end operator


operator * ( byref lhs as vec4f, byref rhs as single ) as vec4f
    
    return type<vec4f>(lhs.x * rhs, lhs.y * rhs, lhs.z * rhs, lhs.w * rhs )
    
end operator


operator vec4f.*= ( byref rhs as matrix )
    
	this = this * rhs
    
end operator


operator / ( byref lhs as vec4f, byref rhs as integer ) as vec4f
    
    return type<vec4f>(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs )
    
end operator


operator / ( byref lhs as vec4f, byref rhs as vec4f ) as vec4f
    
	return type<vec4f>( lhs.x / rhs.x, lhs.y / rhs.y, lhs.z / rhs.z, lhs.w / rhs.w )
    
end operator


operator / ( byref lhs as vec4f, byref rhs as single ) as vec4f
    
    return type<vec4f>(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs )
    
end operator


operator / ( byref lhs as vec4f, byref rhs as double ) as vec4f
    
    return type<vec4f>(lhs.x / rhs, lhs.y / rhs, lhs.z / rhs, lhs.w / rhs )
    
end operator
